package security.IntrusionDetection.BruteforceIntrusion;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import security.Authentication.Base.AuthenticationRequest;
import security.Authentication.Base.IdentifiedUser;
import security.Authentication.Base.UnknownUser;
import security.Authentication.Base.User;
import security.Authentication.UserPass.UserPassRequest;
import security.IntrusionDetection.Base.IntrusionDetection;

/**
 * BruteForce class which detects a brute force type of attack and locks the account for a number of minutes
 * if an intrusion has been detected. 
 * @author Danut
 *
 */
public class BruteForceIntrusion extends IntrusionDetection{
	private Map<String, UserAccountSecurityMeasures> map = new HashMap<String, UserAccountSecurityMeasures>();
	
	@Override
	public User handleRequest(AuthenticationRequest request){
		if(request instanceof UserPassRequest){
			UserPassRequest userPassRequest = (UserPassRequest)request;
			
			if(map.containsKey(userPassRequest.getUserName())&& map.get(userPassRequest.getUserName()).getNrOfAttempts()>=3)
			{
				UserAccountSecurityMeasures usr = map.get(userPassRequest.getUserName());
				if(usr.getTimeStamp()==null){
					usr.setTimeStamp(new Date());
					return new UnknownUser("The user is blocked because of the many denied login requests", true);
				}
				else {
					Date date = new Date();
					if(date.getTime() - usr.getTimeStamp().getTime()>=1000*60*5)
					{
						usr.setNrOfAttempts(0);
						usr.setTimeStamp(null);
					}
					else
						return new UnknownUser("The user is blocked because of the many denied login requests", true);
				}
				
			}
			

			User usr = next.handleRequest(request);
			
			if(usr instanceof UnknownUser)
			{
				if(map.containsKey(userPassRequest.getUserName())){
					UserAccountSecurityMeasures measures = map.get(userPassRequest.getUserName());
					measures.setNrOfAttempts(measures.getNrOfAttempts()+1);
					map.put(userPassRequest.getUserName(), measures);
				}
				else
					map.put(userPassRequest.getUserName(), new UserAccountSecurityMeasures());
			}
			if(usr instanceof IdentifiedUser)
			{
				if(map.containsKey(userPassRequest.getUserName()))
					map.get(userPassRequest.getUserName()).setNrOfAttempts(0);
			}
			return usr;
		} else {
			return passRequestToNext(request);
		}
}
	
	@Override
	public boolean isPossibleIntrusion(AuthenticationRequest auth) {
		
		return true;
	}
	
	
}
